iT邦幫忙

2026 iThome 鐵人賽

DAY 19
0
自我挑戰組

Laravel 讀碼源系列 第 19

鋼琴留言版的後端 程式碼

  • 分享至 

  • xImage
  •  

鋼琴留言版
https://laihao.vaserver.com/gbook

可以實際測試
也歡迎大家一起來學習喔
https://www.pressplay.cc/project/9D489B43D08BD198FDEB03ECDEFAC161/about

資料庫-這裡只有單一一個

MVC架構-
MODEL
前端
後端

後端-程式碼

<?php
namespace App\Http\Controllers;
use App\Models\Gbook;
use Illuminate\Http\Request;

class GbookController extends Controller
{
    public function index()
    {
        $gbooks = Gbook::all();
        return view('gbook.index', ['gbooks' => $gbooks]);
    }

    public function create()
    {
        return view('gbook.create');
    }

    public function store(Request $request)
    {
        $request->validate([
            'gbook_poser' => 'required|max:20',
            'gbook_kind'  => 'required',
            'gbook_title' => 'required|max:30',
            'gbook_msg'   => 'required|max:200',
        ]);

        Gbook::create([
            'gbook_poser' => $request->gbook_poser,
            'gbook_kind'  => $request->gbook_kind,
            'gbook_title' => $request->gbook_title,
            'gbook_msg'   => $request->gbook_msg,
        ]);

        return redirect()->route('gbook.index')->with('success', '留言新增成功!');
    }
}

這是一個 Laravel 的 GbookController 控制器,負責處理留言資料的列表顯示、留言表單與新增留言。它會搭配前面建立的 Gbook Model,以及 gbook.indexgbook.create 兩個 Blade 視圖使用。

一、引入類別

namespace App\Http\Controllers;

表示這個控制器位於:

app/Http/Controllers/GbookController.php
use App\Models\Gbook;

引入前面建立的 Gbook Model,之後才能使用:

Gbook::all();
Gbook::create();
use Illuminate\Http\Request;

引入 Laravel 的 HTTP 請求物件,用來讀取表單送出的資料及執行驗證。

二、控制器類別

class GbookController extends Controller

建立名為 GbookController 的控制器,並繼承 Laravel 的基礎 Controller

這個控制器主要包含三個方法:

index()  → 顯示留言列表
create() → 顯示新增留言表單
store()  → 接收並儲存表單資料

這三個方法正是 Laravel 常見的資源式控制器流程。Laravel 的 resource route 會為 createstore 等操作建立對應路由。 api.laravel

三、index():顯示所有留言

public function index()
{
    $gbooks = Gbook::all();

    return view('gbook.index', ['gbooks' => $gbooks]);
}

1. 查詢所有資料

$gbooks = Gbook::all();

這會透過 Gbook Model 查詢 gbook 資料表中的全部資料。

大致相當於:

SELECT * FROM gbook;

查詢結果會放進:

$gbooks

這通常是一個 Eloquent Collection。

2. 回傳 Blade 視圖

return view('gbook.index', ['gbooks' => $gbooks]);

回傳:

resources/views/gbook/index.blade.php

並把 $gbooks 傳給視圖。

在 Blade 中可以使用:

@foreach ($gbooks as $gbook)
    {{ $gbook->gbook_title }}
    {{ $gbook->gbook_msg }}
@endforeach

因此整個流程是:

Controller 查詢資料
        ↓
取得 $gbooks
        ↓
傳給 gbook.index 視圖
        ↓
Blade 顯示留言

四、create():顯示新增表單

public function create()
{
    return view('gbook.create');
}

這個方法只負責顯示新增留言的畫面,不會寫入資料庫。

它會回傳:

resources/views/gbook/create.blade.php

例如對應的 Blade 表單可能是:

<form method="POST" action="{{ route('gbook.store') }}">
    @csrf

    <input type="text" name="gbook_poser">
    <input type="text" name="gbook_kind">
    <input type="text" name="gbook_title">
    <textarea name="gbook_msg"></textarea>

    <button type="submit">送出</button>
</form>

@csrf 很重要,因為 Laravel 會檢查表單是否包含合法的 CSRF Token。

五、store():接收新增資料

public function store(Request $request)

這個方法處理表單送出的 POST 請求。

Laravel 會把請求內容放進 $request 物件中。

例如表單送出:

gbook_poser = 學生
gbook_kind  = 初級
gbook_title = 許願
gbook_msg   = 卡農

就可以透過以下方式取得:

$request->gbook_poser
$request->gbook_kind
$request->gbook_title
$request->gbook_msg

也可以使用較明確的寫法:

$request->input('gbook_msg');

六、資料驗證

$request->validate([
    'gbook_poser' => 'required|max:20',
    'gbook_kind'  => 'required',
    'gbook_title' => 'required|max:30',
    'gbook_msg'   => 'required|max:200',
]);

這段會驗證表單資料。

gbook_poser

'gbook_poser' => 'required|max:20',

表示:

  • 必填。
  • 最多 20 個字元。

對應資料表:

gbook_poser varchar(20) NOT NULL

gbook_kind

'gbook_kind' => 'required',

表示這個欄位必須填寫,但沒有設定長度限制。

由於資料表是:

gbook_kind varchar(20)

建議加上:

'gbook_kind' => 'required|max:20',

gbook_title

'gbook_title' => 'required|max:30',

表示:

  • 標題必填。
  • 最多 30 個字元。

對應資料表:

gbook_title varchar(30) NOT NULL

gbook_msg

'gbook_msg' => 'required|max:200',

表示:

  • 留言內容必填。
  • 最多 200 個字元。

對應資料表:

gbook_msg varchar(200) NOT NULL

七、驗證失敗時會發生什麼事

例如使用者沒有填寫留言內容:

gbook_msg = 空白

required 驗證就會失敗。

Laravel 會:

  1. 停止執行後面的 Gbook::create()
  2. 自動返回上一頁。
  3. 將錯誤訊息放入 Session。
  4. 將原本輸入的資料保留,方便表單重新顯示。

傳統 HTTP 請求驗證失敗時,Laravel 會重新導向回上一個頁面;驗證錯誤也會暫存到 Session,供視圖顯示。 laravel

在 Blade 表單中可以顯示錯誤:

@error('gbook_msg')
    <div class="text-danger">{{ $message }}</div>
@enderror

也可以保留原本填寫的內容:

<input
    type="text"
    name="gbook_title"
    value="{{ old('gbook_title') }}"
>

八、新增資料到資料庫

Gbook::create([
    'gbook_poser' => $request->gbook_poser,
    'gbook_kind'  => $request->gbook_kind,
    'gbook_title' => $request->gbook_title,
    'gbook_msg'   => $request->gbook_msg,
]);

這段會建立一筆新的留言。

它依賴前面 Model 中的:

protected $fillable = [
    'gbook_poser',
    'gbook_kind',
    'gbook_title',
    'gbook_msg',
    'gbook_date',
];

如果欄位沒有放入 $fillable,使用 Gbook::create() 批次寫入時就不會允許該欄位。

大致會產生類似 SQL:

INSERT INTO gbook
(
    gbook_poser,
    gbook_kind,
    gbook_title,
    gbook_msg
)
VALUES
(
    '學生',
    '初級',
    '許願',
    '卡農'
);

這裡沒有指定:

'gid'

所以 gid 會由 MySQL 的 AUTO_INCREMENT 自動產生。

也沒有指定:

'gbook_date'

因此會使用資料表欄位的:

DEFAULT CURRENT_TIMESTAMP

自動產生日期時間。

九、重新導向並顯示成功訊息

return redirect()
    ->route('gbook.index')
    ->with('success', '留言新增成功!');

這段分成兩部分。

1. 導向命名路由

->route('gbook.index')

表示新增成功後,跳轉至名稱為:

gbook.index

的路由。

常見路由設定如下:

use App\Http\Controllers\GbookController;

Route::get('/gbook', [GbookController::class, 'index'])
    ->name('gbook.index');

Route::get('/gbook/create', [GbookController::class, 'create'])
    ->name('gbook.create');

Route::post('/gbook', [GbookController::class, 'store'])
    ->name('gbook.store');

2. 傳送一次性成功訊息

->with('success', '留言新增成功!');

將成功訊息暫存到 Session。

gbook.index Blade 中可以這樣顯示:

@if (session('success'))
    <div class="alert alert-success">
        {{ session('success') }}
    </div>
@endif

這種訊息通常只顯示一次。使用者重新整理頁面後,Flash Session 通常就不會再次出現。

十、完整執行流程

使用者開啟新增頁面:

GET /gbook/create
        ↓
GbookController@create
        ↓
顯示 gbook.create

使用者填寫表單並送出:

POST /gbook
        ↓
GbookController@store
        ↓
驗證資料

如果驗證失敗:

返回表單頁面
顯示錯誤訊息
保留原本輸入內容

如果驗證成功:

Gbook::create()
        ↓
寫入 gbook 資料表
        ↓
MySQL 自動產生 gid 和 gbook_date
        ↓
重新導向 gbook.index
        ↓
顯示「留言新增成功!」

這個控制器負責三個主要功能:

方法 功能 視圖或操作
index() 顯示所有留言 gbook.index
create() 顯示新增留言表單 gbook.create
store() 驗證並儲存留言 寫入 gbook

核心流程就是:

顯示表單
→ 接收資料
→ 驗證資料
→ 寫入資料庫
→ 返回留言列表
→ 顯示成功訊息

這個 Controller 已經和前面的 Gbook Model、gbook 資料表正確配合。

明天就來說明前端~


上一篇
鋼琴留言版的MODEL
下一篇
鋼琴留言版的前端 程式碼
系列文
Laravel 讀碼源22
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言